#ifndef _CLIENT_HPP
#define _CLIENT_HPP

#include <sys/types.h>
#include <sys/socket.h>
#include <cstring>
#include <unistd.h>

class Client {
public:
    explicit Client(int sockfd) : _sockfd(sockfd) {
        _recvBuffer = new char[_recvSize];
        _sendBuffer = new char[_sendSize];
    }

    ~Client() {
        //close(_sockfd);
        delete[] _recvBuffer;
        delete[] _sendBuffer;
        _recvBuffer = nullptr;
        _sendBuffer = nullptr;
    }

    int Sockfd() const {
        return _sockfd;
    }

    bool NeedWrite() const {
        return _sendLen > 0;
    }

    int RecvData() {
        if (_recvSize > _recvLen) {
            char* buffer = _recvBuffer + _recvLen;
            int ret = recv(_sockfd, buffer, _recvSize - _recvLen, 0);
            if (ret <= 0) {
                return -1;
            }
            _recvLen += ret;
            _recvBuffer[_recvLen] = 0;
            _recvFull = 0;
        } else {
            _recvFull++;
        }
        return 0;
    }

    char* GetData() const {
        return _recvBuffer;
    }

    int DataLen() const {
        return _recvLen;
    }

    void PopData(int len) {
        len = _recvLen - len > 0 ? len : _recvLen;
        memcpy(_recvBuffer, _recvBuffer + len, len);
        _recvLen -= len;
    }

    bool PushData(const char* data, int dataLen) {
        if (dataLen + _sendLen > _sendSize) {
            _sendFull++;
            return false;
        }
        memcpy(_sendBuffer + _sendLen, data, dataLen);
        _sendLen += dataLen;
        _sendFull = 0;
        return true;
    }

    int WriteData() {
        int ret = send(_sockfd, _sendBuffer, _sendLen, 0);
        if (ret <= 0) {
            return -1;
        }
        if (ret == _sendLen) {
            _sendLen = 0;
            memset(_sendBuffer, '\0', _sendSize);
        } else if (ret > 0) {
            _sendLen -= ret;
            memcpy(_sendBuffer, _sendBuffer + ret, _sendLen);
        }
        return 0;
    }

private:
    char* _recvBuffer {nullptr};
    int _recvSize {8192};
    int _recvLen {0};
    int _recvFull {0};

    char* _sendBuffer {nullptr};
    int _sendSize {8192};
    int _sendLen {0};
    int _sendFull {0};

    int _sockfd {0};
};

#endif